#include "head.h"
int sendfd(int sockfd, int fdtosend){
    struct msghdr hdr;
    bzero(&hdr,sizeof(hdr)); // 把name部分置空，不能省略
    // 消息正文
    struct iovec vec[2];//管理离散的区域
    char buf1[] = "hello";//离散区域的一个碎片
    char buf2[] = "world";
    vec[0].iov_base = buf1;//管理碎片0的地址和长度
    vec[0].iov_len = 5;
    vec[1].iov_base = buf2;//管理碎片1的地址和长度
    vec[1].iov_len = 5;
    hdr.msg_iov = vec;//hdr管理要发送的正文部分的信息
    hdr.msg_iovlen = 2;//正文部分是离散的区域，区域中有两个碎片
    // 控制信息字段 data要存入一个文件描述符int
    // 因为cmsghdr是变长数组，所以只能申请在堆上
    struct cmsghdr *pcmsg = (struct cmsghdr *)calloc(1,CMSG_LEN(sizeof(int))); 
    pcmsg->cmsg_len = CMSG_LEN(sizeof(int));
    pcmsg->cmsg_level = SOL_SOCKET;
    pcmsg->cmsg_type = SCM_RIGHTS;//说明传递的是文件描述符
    // 先找到data的首地址，把fdtosend填入
    *(int *)CMSG_DATA(pcmsg) = fdtosend; // 首地址强转成int *，再解引用
    hdr.msg_control = pcmsg;//hdr管理消息的控制信息字段
    hdr.msg_controllen = CMSG_LEN(sizeof(int));
    // 调用sendmsg函数
    int ret = sendmsg(sockfd,&hdr,0);
    ERROR_CHECK(ret,-1,"sendmsg");
    return 0;
}
int recvfd(int sockfd, int *pfdtorecv){
    struct msghdr hdr;
    bzero(&hdr,sizeof(hdr)); // 把name部分置空，不能省略
    // 消息正文
    struct iovec vec[2];//管理离散的区域
    char buf1[6] = {0};// 将要接收正文部分的内容
    char buf2[6] = {0};
    vec[0].iov_base = buf1;//管理碎片0的地址和长度
    vec[0].iov_len = 5;
    vec[1].iov_base = buf2;//管理碎片1的地址和长度
    vec[1].iov_len = 5;
    hdr.msg_iov = vec;//hdr管理要发送的正文部分的信息
    hdr.msg_iovlen = 2;//正文部分是离散的区域，区域中有两个碎片
    // 控制信息字段 data要存入一个文件描述符int
    // 因为cmsghdr是变长数组，所以只能申请在堆上
    struct cmsghdr *pcmsg = (struct cmsghdr *)calloc(1,CMSG_LEN(sizeof(int))); 
    pcmsg->cmsg_len = CMSG_LEN(sizeof(int));
    pcmsg->cmsg_level = SOL_SOCKET;
    pcmsg->cmsg_type = SCM_RIGHTS;//说明传递的是文件描述符
    hdr.msg_control = pcmsg;//hdr管理消息的控制信息字段
    hdr.msg_controllen = CMSG_LEN(sizeof(int));
    // 调用recvmsg函数
    int ret = recvmsg(sockfd,&hdr,0);
    ERROR_CHECK(ret,-1,"recvmsg");
//    printf("buf1 = %s, buf2 = %s\n", buf1,buf2);
    *pfdtorecv = *(int *)CMSG_DATA(pcmsg);
    return 0;
}
